#pragma once

#include <QtCore/QLibrary>
#include <QtCore/QFile>
#include <QtCore/QDebug>

class LibraryLoader
{  
private:
   LibraryLoader()
   {
   }  
  
   ~LibraryLoader()
   {
   }  

public:
    template <typename T,typename D>
    static D* to(T* t)
    {
        return dynamic_cast<D*>(t);
    }


    template <typename T>
    static T* load(std::string szPlugin)
    {
       QString szAddin = szPlugin.c_str();
       return load<T>(szAddin);
    }

    template <typename T>
    static T* load(QString szPlugin)
    {
#ifndef _Andriod
       QFile file;
       if( file.exists(szPlugin.toStdString().c_str()) == false )
       //if( FileManager::ifFileExist(szPlugin.toStdString()) == false )
       {
//         qCritical() << LOG_HEADER << szPlugin << " not exist.";
          return NULL;
       }
#endif
        T* pPlugin = NULL;

        QLibrary* pLoader = new QLibrary(szPlugin);
        if( pLoader->load() )
        {
           typedef T* (*funInterface)();
           funInterface fun = (funInterface)pLoader->resolve("instance");
           if( fun != nullptr )
           {
               pPlugin = fun();
           }
        }

        if( pPlugin != nullptr)
        {
            pPlugin->setLoader(pLoader);
        }
        else
        {
			QString szError = pLoader->errorString();
//			qCritical() << LOG_HEADER << " load " << szPlugin.toStdString().c_str() << " : " << szError.toStdString().c_str();
            pLoader->unload();
            pLoader->deleteLater();
        }

        return pPlugin;
    }

    // 释放对象
    // 卸载插件
    template <typename T>
    static bool unload(T* pPlugin )
    {
        if( pPlugin == nullptr )
        {
            return false;
        }

        QLibrary* pLoader = pPlugin->getLoader();
        if( pLoader != nullptr )
        {
            pLoader->unload();
        }

        return true;
    }
};  
